﻿using calculatorFrom;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

public class CalculateImpl : Calculate
{
    public string calculate(String expression)
    {
        Console.Out.WriteLine("前缀表达式：" + expression);
        string postfix = infixToPostfix(expression);
        Console.Out.WriteLine("后缀表达式：" + postfix);

        Stack<double> result = new Stack<double>();
        double num = 0;
        for(int i = 0; i < postfix.Length; i++)
        {
            char ch = postfix[i];
            if (char.IsWhiteSpace(ch))
            {
                result.Push(num);
                num = 0;
                // 可以出现连续两个空格，跳过
                while (char.IsWhiteSpace(postfix[i]))
                {
                    i++;
                    continue;
                }
                i--;
                continue;
            }

            if (isOperators(ch))
            {
                // ch是运算符
                double num_b = result.Pop();
                double num_a = result.Pop();
                double temp = elementaryOperation(num_a, num_b, ch);
                result.Push(temp);
                continue;   // 执行下一次循环，下面的代码不执行
            }
            
            if (ch == '.')
            {
                // 是小数点
                num += (ch - '0') / 10;
            }
            else
            {
                // 是数字
                num = num * 10 + (ch - '0');
            }
            

        }

        return result.Pop().ToString();

    }

    bool isOperators(char ch)
    {
        switch (ch)
        { 
            case '+':
            case '-':
            case '×':
            case '÷':
                return true;
            default :
                return false;
        }
    }
    
    // 将中缀表达式转换为后缀表达式
    public string infixToPostfix(string expression)
    {
        Stack<char> operators = new Stack<char>();
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < expression.Length; i++)
        {
            char ch = expression[i];
            if (char.IsWhiteSpace(ch)) continue;
            switch (ch)
            {
                case '×':
                case '÷':
                    while (operators.Count > 0)
                    {
                        char c = operators.Pop();
                        if (c == '(')
                        {
                            operators.Push(c);
                            break;
                        }
                        else
                        {
                            if (c == '+' || c == '-')
                            {
                                operators.Push(c);
                                break;
                            }
                            else
                            {
                                result.Append(" ");
                                result.Append(c);
                            }
                        }
                    }
                    operators.Push(ch);
                    result.Append(" ");
                    break;
                case '+':
                case '-':
                    while (operators.Count > 0)
                    {
                        char c = operators.Pop();   //pop Operator
                        if (c == '(')
                        {
                            operators.Push(c);      //push Operator
                            break;
                        }
                        else
                        {
                            result.Append(" ");
                            result.Append(c);
                        }
                    }
                    operators.Push(ch);
                    result.Append(" ");
                    break;

                case '(':
                    operators.Push(ch);
                    result.Append(" ");
                    break;
                case ')':
                    while (operators.Count > 0)
                    {
                        char c = operators.Pop();
                        if (c == '(')
                        {
                            break;
                        }
                        else
                        {
                            result.Append(" ");
                            result.Append(c);
                        }
                    }
                    result.Append(" ");
                    break;
                default:
                    result.Append(ch);
                    break;
            }
        }
        while (operators.Count > 0)
        {
            result.Append(" ");
            result.Append(operators.Pop()); //pop All Operator
        }
        return result.ToString();
    }

    public double elementaryOperation(double num_a, double num_b, char ope)
    {
        switch (ope)
        {
            case '+':
                return add(num_a, num_b);
            case '-':
                return minus(num_a, num_b);
            case '×':
                return multoply(num_a, num_b);
            case '÷':
                return divide(num_a, num_b);
            default:
                MessageBox.Show("未知的运算符，太高深了！");
                return 0;
        }
    }

    public double add(double num_a, double num_b)
    {
        return num_a + num_b;
    }

    public double minus(double num_a, double num_b)
    {
        return num_a - num_b;
    }

    public double multoply(double num_a, double num_b)
    {
        return num_a * num_b;
    }

    public double divide(double num_a, double num_b)
    {
        return num_a / num_b;
    }

    public double mod(double num_a, double num_b)
    {
        double result = -1;
        while ((result = num_b - num_a) > 0)
        {

        }
        return result;
        throw new NotImplementedException();
    }
}
